package com.example.jedis.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

/**
 * 传统做法（不推荐）	                        使用连接池（推荐）
 * 每次都 new Jedis()，连接/关闭 Redis，开销大	使用连接池从池中获取连接，重复利用，效率高
 * 容易因忘记关闭连接而导致资源泄漏	            池统一管理连接，支持自动释放
 * 不支持连接数限制	                        可配置最大连接数、防止服务器过载
 * <p>
 * JedisPoolConfig 是用来配置连接池行为的类，比如最大连接数、空闲连接数等。合理配置它可以：
 * 保证服务稳定：不让 Redis 被太多连接压垮
 * 提升响应速度：通过复用连接减少建立连接的延迟
 * 防止资源浪费：回收闲置连接，减少内存压力
 */

/**
 * JedisPoolConfig 是用来配置连接池行为的类，比如最大连接数、空闲连接数等。合理配置它可以：
 * 保证服务稳定：不让 Redis 被太多连接压垮
 * 提升响应速度：通过复用连接减少建立连接的延迟
 * 防止资源浪费：回收闲置连接，减少内存压力
 */

/**
 * 项目	                作用/目的
 * JedisPool	        管理 Redis 连接的连接池，避免重复创建销毁连接
 * JedisPoolConfig	    配置连接池的大小、空闲连接、超时设置等
 * 全局初始化方式	        可以写工具类（适用于任何项目），也可用 Spring 注入管理
 */
public class JedisConnectionFactory {

    /**
     * [连接池初始化] --> 创建 minIdle 个空闲连接
     * [程序请求连接] --> 从池中获取（已有空闲 -> 复用；无空闲 -> 创建新连接）
     * [程序用完连接] --> jedis.close() 归还连接（不是断开 Redis）
     * [连接池维护] --> 定期检测无效连接，回收过多的空闲连接
     *        +----------------------+
     *        |  JedisPoolConfig     |  ← 配置连接池参数（连接数、等待时间等）
     *        +----------------------+
     *                   ↓
     *        +----------------------+
     *        |     JedisPool        |  ← 连接池：统一管理多个 Jedis 连接
     *        +----------------------+
     *               ↓       ↓
     *       [Jedis]    [Jedis] ...   ← 每次调用 getResource() 获取一个连接
     */

    private static final JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        // 最大连接数（最多同时连接的 Redis 客户端数）
        poolConfig.setMaxTotal(8);
        // 最大空闲连接（最大允许的空闲 Jedis 连接数）
        poolConfig.setMaxIdle(8);
        // 最小空闲连接（保持的最小空闲 Jedis 连接数）
        poolConfig.setMinIdle(1);
        // 最大等待时间（当连接池耗尽时，新请求最多等待 2000ms）
        poolConfig.setMaxWait(Duration.ofMillis(2000));
        // 取连接时检测
        poolConfig.setTestOnBorrow(true);
        // 归还连接时检测
        poolConfig.setTestOnReturn(true);
        // 空闲连接检测
        poolConfig.setTestWhileIdle(true);
        // 30s 清理
        poolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(30000));
        // 60s 关闭空闲连接
        poolConfig.setMinEvictableIdleDuration(Duration.ofMillis(60000));
        // 创建连接池
        jedisPool = new JedisPool(poolConfig, "192.168.86.130", 6379, 1000, "123456");
    }

    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}
